from typing import List

from fastapi import Depends, Request
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.ext.asyncio import AsyncSession
from common.config.get_db import get_db
import jwt
from common.config.enums import RedisInitKeyConfig
from common.config.env import AppConfig, JwtConfig
from common.utils.common_util import SqlalchemyUtil
from common.utils.log_util import logger
from common.exceptions.exception import  AuthException, ServiceException
from jwt.exceptions import InvalidTokenError
from datetime import  timedelta
from common.config.get_redis import RedisUtil

oauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')


class LoginService:
    @classmethod
    async def get_current_user(
            cls, request: Request = Request, token: str = Depends(oauth2_scheme)
    ):
        """
        根据token获取当前用户信息
        """
        try:
            if token.startswith('Bearer'):
                token = token.split(' ')[1]
            payload = jwt.decode(token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm])
            login_id= payload.get('用户的令牌唯一标识')
            session_id: str = payload.get('session_id')
            if login_id is None:
                logger.warning('token不合法')
                raise AuthException(data='', msg='token不合法')
        except InvalidTokenError:
            logger.warning('用户token已失效，请重新登录')
            raise AuthException(data='', msg='用户token已失效，请重新登录')
        redis_token = await  RedisUtil.get_redis_value(request, f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{login_id}:{session_id}')
        #     判断当前token和redis的token是否一致
        if token == redis_token:
            # 此方法可实现同一账号同一时间只能登录一次
            await RedisUtil.set_redis_value(request,
                                      f'{RedisInitKeyConfig.ACCESS_TOKEN.key}:{login_id}:{session_id}',
                                      redis_token,
                                      timedelta(minutes=JwtConfig.jwt_redis_expire_minutes))
            return payload
        else:
            logger.warning('用户token不合法，请重新登录')
            raise AuthException(data='', msg='用户token不合法，请重新登录')

